<template>
  <div>
    <div class="nav">
      <div class="city">{{ city }}</div>
      <input type="text" v-model="choseCity" placeholder="请输入城市" @keyup.enter="searchCity">
      <select id="choseShape">
        <option></option>
        <option value="LineString">绘制线</option>
        <option value="Polygon">绘制面</option>
        <option value="Circle">绘制圆</option>
      </select>
      <select id="choseType">
        <option></option>
        <option value="bus">公交站</option>
        <option value="hospital">医院</option>
        <option value="school">学校</option>
      </select>
    </div>
    <div id="map">
      <div class="overlay"></div>

    </div>

  </div>

</template>
<script setup>
import { ref, onMounted } from 'vue'
import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import XYZ from 'ol/source/XYZ';
import GeoJson from 'ol/format/GeoJSON';
import { Fill, Stroke, Style } from 'ol/style';
import Draw from 'ol/interaction/Draw';
import { Point } from 'ol/geom';
import Icon from 'ol/style/Icon';
import Feature from 'ol/Feature';
import Cluster from 'ol/source/Cluster';
import CircleStyle from 'ol/style/Circle';
import Text from 'ol/style/Text';
import Overlay from 'ol/Overlay';
import Select from 'ol/interaction/Select';
import { pointerMove } from "ol/events/condition";
import ol_featureAnimation_Fade from 'ol-ext/featureanimation/Fade';

const city = ref('')
const choseCity = ref('')
const gaodeKey = "f39d7d03d88e44202332bb4e650a1c15"
const adcoade = ref('')
let map
let draw
let value
let view = new View({
  projection: 'EPSG:4326',
  center: [112.4543, 34.6197], // 洛阳的经纬度
  zoom: 4// 初始缩放级别  

});
let cityLayer
let overlay
let gaodeLayer = new TileLayer({
  source: new XYZ({
    url: "http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}"
  })
})

onMounted(async () => {
  map = new Map({
    target: "map",
    layers: [
      gaodeLayer,
    ],
    view: view,
  });
  let vectorLayer3 = new VectorLayer({
    source: new VectorSource({
      url: "https://geo.datav.aliyun.com/areas_v3/bound/100000_full_city.json",
      format: new GeoJson()
    }),

  });
  map.addLayer(vectorLayer3);

  let overlay = new Overlay({
    element: document.querySelector(".overlay"),
  });
  map.addOverlay(overlay);
  map.on("click", function (e) {
    let lonlat = e.coordinate;
    let f = vectorLayer3.getSource().getFeaturesAtCoordinate(lonlat)[0];
    if (f) {
      let name = f.get("name");
      let center = f.get("center");
      //获取到overlay对应的dom元素
      let element = overlay.getElement();
      element.innerHTML = `
      <div>
        <p>城市:${name}</p>
        <p>精度${center[0]}</p>
        <p>纬度${center[1]}</p>
      </div>
    `;
      //设置overlay的坐标位置
      overlay.setPosition(center);
    } else {
      overlay.setPosition(undefined);
    }
  });
  let select = new Select({
    hitTolerance: 10, //增加选中的容差
    condition: pointerMove, //修改选中的交互条件
  });
  map.addInteraction(select);
  select.on("select", function (e) {
    const selected = e.selected[0];
    selected.setStyle(new Style({
      fill: new Fill({
        color: 'rgba(255, 0, 0, 0.5)'
      }),
      stroke: new Stroke({
        color: 'black',
        width: 2
      })
    }))
  })
  setTimeout(async () => {
    const temp = await fetch('https://restapi.amap.com/v3/ip?key=' + gaodeKey)
    let data = await temp.json()
    console.log(data)
    city.value = data.city
    adcoade.value = data.adcode
    cityLayer = new VectorLayer({
      source: new VectorSource({
        url: `https://geo.datav.aliyun.com/areas_v3/bound/${adcoade.value}.json`,
        format: new GeoJson()
      }),
      style: new Style({
        fill: new Fill({
          color: 'rgba(255, 0, 0, 0.5)'

        }),
        stroke: new Stroke({
          color: 'black',
          width: 2
        })

      }),


    })
    map.addLayer(cityLayer)
    view.animate({
      zoom: 8,
      duration: 1000,
    })
  })
  let vectorLayer = new VectorLayer({
    source: new VectorSource(),
    style: new Style({
      stroke: new Stroke({
        color: "red",
        width: 2,
      }),
      fill: new Fill({
        color: "pink",
      }),
    }),
  });
  map.addLayer(vectorLayer);
  let vectorLayer2 = new VectorLayer({
    source: new VectorSource(),
    style: new Style({
      stroke: new Stroke({
        color: "blue",
        width: 2,
      }),
      fill: new Fill({
        color: "lightblue",
      }),
    }),
  });

  choseShape.onchange = function () {
    //保证只添加一个绘图交互
    //绘制点要素 通常需要设置style里的Image或者text
    map.removeInteraction(draw);
    draw = null;
    let value = this.value;
    draw = new Draw({
      type: value,
      source: vectorLayer.getSource(),
    });
    map.addInteraction(draw);
  };

  choseType.onchange = function () {
    // 清除map之前的点击事件
    const listeners = map.getListeners('click') || [];
    listeners.forEach(listener => {
      map.un('click', listener);
    });
    value = this.value;
    console.log(value)
    // 给地图添加点击事件
    const mapClickHandler = function (e) {
      console.log("点击事件")
      const coordinate = e.coordinate;
      //点是一个要素
      const point = new Feature({
        geometry: new Point(coordinate),
      });

      point.setStyle(new Style({
        image: new Icon({
          src: `/public/icon/${value}.png`,
          // 根据zoom级别来设置图片大小
          scale: 0.8 / view.getZoom(),
        }),
      }));
      vectorLayer2.getSource().addFeature(point);
      const source = vectorLayer2.getSource();

      let clusterSource = new Cluster({
        source: source,
        distance: 20,
      });
      let layer = new VectorLayer({
        source: clusterSource,
        style: clusterStyle,
      });
      function clusterStyle(feature) {
        //获取点要素是否聚合
        const size = feature.get("features").length;
        let style = new Style();
        if (size === 1) {
          const image = feature.get("features")[0].getStyle().getImage();
          // 获取feature的style
          style.setImage(image);
        } else {
          //显示聚合的点的数量
          style.setImage(
            new CircleStyle({
              radius: 10,
              fill: new Fill({
                color: "red",
              }),
            })
          );
          style.setText(
            new Text({
              text: size.toString(),
              fill: new Fill({
                color: "#fff",
              }),
            })
          );
        }
        return style;
      }
      let Fade = new ol_featureAnimation_Fade({
        duration: 1000,
        easing: "easeOut",
      });
      layer.animateFeature(point, Fade);
      map.addLayer(layer);
    }
    if (value) {
        map.on('click', mapClickHandler);
        console.log("添加点击事件")
      }
  }

})


async function searchCity() {
  const temp = await fetch(`https://restapi.amap.com/v3/geocode/geo?address=${choseCity.value}&key=${gaodeKey}`)
  let data = await temp.json()
  if (data.status === '0') {
    alert('未找到该城市')
  }
  city.value = data.geocodes[0].city
  adcoade.value = data.geocodes[0].adcode
  let center = data.geocodes[0].location.split(',').map(Number)
  cityLayer.getSource().clear()
  let citySource = cityLayer.getSource()
  citySource.clear()
  // citySource.setUrl(`https://geo.datav.aliyun.com/areas_v3/bound/${adcoade.value}.json`)
  cityLayer = new VectorLayer({
    source: new VectorSource({
      url: `https://geo.datav.aliyun.com/areas_v3/bound/${adcoade.value}.json`,
      format: new GeoJson()
    }),
    style: new Style({
      fill: new Fill({
        color: 'rgba(255, 0, 0, 0.5)'

      }),
      stroke: new Stroke({
        color: 'black',
        width: 2
      })

    }),

  })
  map.addLayer(cityLayer)
  view.animate({
    center: center,
    zoom: 8,
    duration: 1000,
  })
}

</script>



<style scoped>
.nav {
  height: 60px;
  width: 100%;
  background-color: skyblue;
  display: flex;
  align-items: center;
  padding-left: 10vw;
  gap: 40px;
}

#map {
  height: calc(100vh - 60px);
  width: 100%;
}
</style>